package com.example.nutritionmanager.viewModels

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.nutritionmanager.api.CalorieService
import com.example.nutritionmanager.data.UserProfileDataStore
import com.example.nutritionmanager.event.EventBus
import com.example.nutritionmanager.event.IntakeRefreshEvent
import com.example.nutritionmanager.home.getCurrentDate
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import javax.inject.Inject

sealed class IntakeState {
    data class Idle(val date: String = getCurrentDate()) : IntakeState()
    object Loading : IntakeState()
    data class Success(val date: String, val amounts: Double) : IntakeState()
    data class Error(val date: String, val error: String) : IntakeState()
}
sealed class WeekIntakeState {
    data class Idle(val date: String = getCurrentDate()) : WeekIntakeState()
    object Loading : WeekIntakeState()
    data class Success(val date: String, val amounts: List<Double>) : WeekIntakeState()
    data class Error(val date: String, val error: String) : WeekIntakeState()
}
@HiltViewModel
class IntakeViewModel @Inject constructor(
    private val calorieService: CalorieService,
    private val userProfileDataStore: UserProfileDataStore
) : ViewModel() {

    private val _intakeState = MutableStateFlow<IntakeState>(IntakeState.Idle())
    val intakeState: StateFlow<IntakeState> get() = _intakeState.asStateFlow()

    private val _weekIntakeState = MutableStateFlow<WeekIntakeState>(WeekIntakeState.Idle())
    val weekIntakeState: StateFlow<WeekIntakeState> get() = _weekIntakeState.asStateFlow()

    private val _selectedDate = MutableStateFlow<String>(getCurrentDate())
    val selectedDate: StateFlow<String> get() = _selectedDate.asStateFlow()

    private val _currentCalorie = MutableStateFlow<Float>(0f)
    val currentCalorie: StateFlow<Float> get() = _currentCalorie.asStateFlow()

    // 添加最大热量的状态
    private val _maxCalorie = MutableStateFlow<Float>(2000f)
    val maxCalorie : StateFlow<Float> get() = _maxCalorie.asStateFlow()

    // 周内热量
    private val _weekCalories = MutableStateFlow<List<Int>>(List(7) { 0 })
    val weekCalories : StateFlow<List<Int>> get() = _weekCalories.asStateFlow()

    init {
        // 监听最大热量变化
        viewModelScope.launch {
            // 启动刷新事件监听
            EventBus.events
                .filterIsInstance<IntakeRefreshEvent.RefreshData>()
                .collect { event ->
                    refreshIntakeData()
                }
            userProfileDataStore.maxCalorie.collect { max ->
                _maxCalorie.value = max.toFloat()
                // 当最大热量变化时自动刷新数据
                loadIntakeData(_selectedDate.value)
            }
        }
        loadIntakeData(_selectedDate.value)
        // 目前为当前日期的前一周
        // TODO: 按周选择现实
        loadWeekIntake(getCurrentDate())
    }

    fun refreshIntakeData() {
        loadIntakeData(_selectedDate.value)
        loadWeekIntake(getCurrentDate())
    }

    fun updateDate(newDate: String) {
        _selectedDate.value = newDate
        loadIntakeData(newDate)
    }

    // 获取每日热量摄入情况
    private fun loadIntakeData(date: String) {
        viewModelScope.launch {
            _intakeState.value = IntakeState.Loading
            try {
                val current = calorieService.getDayCalories(date).body()?: 0.0
                val max = userProfileDataStore.getUserProfile.first()?.targetCalories?.toDouble() ?: 2000.0
                _intakeState.value = IntakeState.Success(date, current)
                _currentCalorie.value = current.toFloat()
                _maxCalorie.value = max.toFloat()
            } catch (e: Exception) {
                _intakeState.value = IntakeState.Error(date, e.message ?: "Unknown error")
                // 处理错误
            }
        }
    }

    // 获取周内热量摄入情况
    private fun loadWeekIntake(date: String){
        viewModelScope.launch {
            _weekIntakeState.value = WeekIntakeState.Loading
            try {
                val calories = calorieService.getWeekCalories(date).body()?: List(7) { 0.0 }
                _weekIntakeState.value = WeekIntakeState.Success(date, calories)

                _weekCalories.value = calories.map { it.toInt() }
            } catch (e: Exception) {
                _weekIntakeState.value = WeekIntakeState.Error(date, e.message ?: "Unknown error")
            }
        }
    }
}
